iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 2
0
自我挑戰組

Some thing with Reason系列 第 2

基本型態 - Part I

  • 分享至 

  • xImage
  •  

Basic Type

在每個程式語言中都會有一些基本的型態

Reason 屬於強型態的程式語言

這裡介紹的基本型態的變數型態有

  • Boolean
  • 數字
  • 字串
  • 字元

Type

TypeReason 的亮點之一

let 不一定需要宣告 類型

let score = 10;

Reason 知道 score 是個 int 型別,透過其值 10 判斷出來。這個稱之為 推斷(inference)

變數宣告(Let binding)

在介紹變數型態之前要先介紹一下如何宣告變數

Reason 中只有使用 let 來宣告變數

let a: string = "hello";

雖然在 Reason 中已經宣告,但是在編譯成功後依舊不會看到這個變數

因為當尚未使用到之前是不會產生在結果中

let a: string = "hello";
Js.log(a);

但是當我們開始使用之後,編譯結果就會出現

Result:

// Generated by BUCKLESCRIPT VERSION 4.0.5, PLEASE EDIT WITH CARE
'use strict';

var a = "hello";

console.log(a);

exports.a = a;
/*  Not a pure module */

另外 Reason 是屬於 Block Scope

if (displayGreeting) {
  let message = "Enjoying the docs so far?";
  print_endline(message)
};
/*這裡不能呼叫 message*/

也可以這樣處理

let message = {
  let part1 = "hello";
  let part2 = "world";
  part1 ++ " " ++ part2
};

Js.log(message);

這樣在外層會無法呼叫 part1, part2

message 會等於 part1 ++ " " ++ part2 的字串組合

編譯後的結果會是

'use strict';

var message = "hello world";

console.log(message);

exports.message = message;

而且預設使用 let 宣告的變數都是 Immutable

let a: string = "hello";
a = "hello world";

這邊會得到一個錯誤訊息

>>>> Start compiling
[1/1] Building src/Demo-HelloWorld.cmj

  We've found a bug for you!
  /Users/tomas/Documents/iThome/2018/hello-world/src/Demo.re 2:1-17

  1 │ let a: string = "hello";
  2 │ a = "hello world";

  The value a is not an instance variable

>>>> Finish compiling(exit: 1)

但是可以重複使用 let 宣告同一個變數

let message = "hello";
Js.log(message); /* Prints "hello" */
let message = "bye";
Js.log(message); /* Prints "bye" */

Type system

雖然 Reason 是屬於強型態,但是也有留一些彈性

若你沒有宣告變數型態的時候,他會自動進行型態推導

let a = "1";

let b = a ++ "hello";

Js.log(b); /* 1hello */

但是如果使用數字的運算的話

let a = 1;

let b = a ++ "hello";

Js.log(b); /* Error: */

會得到了一個錯誤

型態錯誤

訊息會相當清楚地告知是哪一個部分錯誤

對於 debug 會相當有利

Boolean

布林值在各個程式語言中佔有相當重要的基本判斷依據

而且在 Javascript 中也是一項令人相當頭痛的變數型態

常常會有很多不小心造成了很多 bug

let testNum = 1;
let isZero: bool = testNum === 0;
Js.log(isZero);

有趣的是編譯結果會是

// Generated by BUCKLESCRIPT VERSION 4.0.5, PLEASE EDIT WITH CARE
'use strict';


var isZero = false;

console.log(isZero);

var testNum = 1;

exports.testNum = testNum;
exports.isZero = isZero;

他並未依據我的順序來做編譯

而是做了一些優化

因為 isZero 比較的是一個常數

所以不論怎樣執行,最後的結果一定是 false

所以他優先宣告了 var isZero = false;

然後在宣告 testNum

基本的布林運算子

  • && - and
  • || - or
  • ! - not
  • <=, >=, <, >
  • == - structural equal
  • === - referential equal
  • != - structural not equal
  • !== - referential equal

運算子中比較有趣的是 =====

let tuple1 = (1, 2, 3);
let tuple2 = (1, 2, 3);
let tuple3 = tuple2;

Js.log(tuple1 == tuple2); /* true */
Js.log(tuple1 == tuple3); /* true */
Js.log(tuple1 === tuple2); /* false */
Js.log(tuple1 === tuple3); /* false */
Js.log(tuple2 === tuple3); /* true */

== 是比較結構是否相等
=== 是比較來源是否相同

數字

let zero: int = 0;
let floatNumber: float = 0.1;

Js.log(zero); /* 0 */
Js.log(floatNumber); /* 0.1 */

/* zero === floatNumber will got Error by compiler*/
  • int - 整數
  • float - 浮點數

數字的相加

let addResult = 1 + 1;
Js.log(addresult);/* 2 */

let floatAddResult = 1.1 + 1.2; /* get compiler Error (WTF) */
Js.log(floatAddResult);

Float 的相加要使用另外一個符號 +.

let addResult = 1 + 1;
Js.log(addresult);/* 2 */

let floatAddResult = 1.1 +. 1.2; /* 2.3 */
Js.log(floatAddResult);

int 與 float 的比大小

因為 Reason 是強型別的語言

let twoBiggerThanOne = 2 > 1;
Js.log(twoBiggerThanOne);

intfloat 是不同的型別

無法直接地做比較

所以要先使用 float_of_intint 轉成 float

float_of_int(2) > 1.2; /* true */

string

" 使用雙引號宣告的為字串

' 使用單引號宣告的為字元

字元只能有一個字母

let name: string = "Tomas";
let yourName: string = "哈囉世界!";
let a: char = 'a';

Js.log(name);
Js.log(a);
Js.log(yourName); /* \xe5\x93\x88\xe5\x9b\x89\xe4\xb8\x96\xe7\x95\x8c! */

在編譯的時候要注意的是如果是中文的話預設是 Unicode

在宣告的時候要先進行處理

而使用 j 除了處理 Unicode 也可以用變數 (類似 ES6 Template)

let name: string = "Tomas";
let yourName: string = {js|哈囉世界!|js};
let world = {js|世界|js};
let helloWorld = {j|你好,$world|j};
let a: char = 'a';

Js.log(name);
Js.log(a);
Js.log(yourName); /* 哈囉世界! */

BuckleScript 編譯前會先尋找 jsj 進行處理

另外字串的相加使用 ++

let hello = "Hello";
let world = "World"
Js.log(hello ++ " " ++ world); /* console.log("Hello World"); */

也可此參考 Reason 的 string API文件


上一篇
第一天一定要來個 Hello World
下一篇
基本型態 - Part II
系列文
Some thing with Reason30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言